/***********************************************************************************************//**
*\n  @file       main_test.c
*\n  @brief      主程序，测试程序
*\n  @details
*\n -----------------------------------------------------------------------------------
*\n  文件说明：
*\n
*\n -----------------------------------------------------------------------------------
*\n  版本:   	修改人:       修改日期:    		描述:
*\n  V0.01  	项目组        2020.2.17        创建
*\n
***************************************************************************************************/

/**************************************************************************************************
* 头文件
***************************************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <string.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h> 
#include <sys/mman.h>
#include <errno.h>
#include <pthread.h>

#include "fpga_io.h"
#include "spi_ctrl.h"
//#include "spi_uds.h"
#include "commucationIF.h"

/**************************************************************************************************
* 宏定义、结构定义
***************************************************************************************************/
#define MAIN_DEBUG   	1		     ///< 调试信息开关
#define BUFFER_MAX_SIZE (2 * 1024)   ///< 最大数据长度


/**************************************************************************************************
* 全局变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有函数声明、定义
***************************************************************************************************/
/// 调试信息
#if MAIN_DEBUG
#define PCL_NONE				 "\e[0m"
#define PCL_YELLOW				 "\e[1;33m"
#define PCL_RED 				 "\e[0;31m"

#define dbg_printf(...)   \
	do{ printf(PCL_NONE "[%s,%d,%s] ", __FILE__, __LINE__, __func__); \
		printf(__VA_ARGS__); }while(0)

	
#define dbg_info(buffer,size, ...)   \
	do{ 	printf(PCL_NONE "[%s,%d,%s] ", __FILE__, __LINE__, __func__); \
			printf(__VA_ARGS__); \
			char *p = (char*)buffer; \
			int ii_; \
			for (ii_=0; ii_<(int)size; ii_++) \
			{   printf("%02x ", *(p++)); if ((ii_ != 0) && (ii_ % 32 == 0)) printf("\n"); \
			} \
			if (ii_ % 32 != 0) printf("\n"); \
	}while(0)

	
#define dbg_warn(...)   \
		do{ printf(PCL_YELLOW "[warn,%s,%d,%s] ", __FILE__, __LINE__, __func__); \
		printf(__VA_ARGS__); }while(0)

#define dbg_error(...)   \
	do{ printf(PCL_RED "[error,%s,%d,%s] ", __FILE__, __LINE__, __func__); \
		printf(__VA_ARGS__); }while(0)

#define dbg_fatal(...)   \
	do{ printf(PCL_RED "[fatal,%s,%d,%s] ", __FILE__, __LINE__, __func__); \
		printf(__VA_ARGS__); }while(0)

#else
#define dbg_error(...)
#define dbg_fatal(...)
#define dbg_warn(...)
#define dbg_printf(...)
#define dbg_info(...)
#endif


/**************************************************************************************************
* 全局函数声明、定义
***************************************************************************************************/
#if 0
//--------------------------------------------------------------------------------------------------
// 测试代码 (测试spi物理、链路层接口)
//--------------------------------------------------------------------------------------------------
void *test_task(void *arg)
{
	int ret;
	static char tx_buf[32*1024] = {0}; 
	
	// 打开
	ret = SpiOpen();  
	if (ret < 0)
	{
		dbg_error("SPI_Open() error \n");
		goto exit1;
	}

	while(1)
	{
		for(volatile int i=0; i<1000000; i++);
		memset(tx_buf, 0x00, sizeof(tx_buf));
		SpiWrite(tx_buf,  128);
	}

exit1:
	// 关闭
	SpiClose();   
	pthread_exit(NULL);

}

int  init_task(void)
{
	int ret = 0;

	usleep(100*1000);
	static pthread_t vdma_tid = 0;
	ret = pthread_create(&vdma_tid, NULL, test_task, NULL);
	if(0 != ret)
	{
		printf("pthread_create failed : %s\n", strerror(errno));
		return (-1);
	}
	usleep(100*1000);
	return 0;
}


int main(int argc, char *argv[])
{
	int ret = 0;
	static char tx_buf[32*1024] = {0}; 

	struct timeval now;
	struct timeval now1;

	// 打开
	ret = SpiOpen();  
	if (ret < 0)
	{
		dbg_error("SPI_Open() error \n");
		return -1;
	}

	init_task();
	for(int i=0; i<1000; ++i)
	{
		// 收发数据
		for (volatile int j=0; j<100000; ++j);
		memset(tx_buf, 0x00, sizeof(tx_buf));

    	gettimeofday(&now, NULL);
		SpiWrite(tx_buf,  128);
    	gettimeofday(&now1, NULL);

		double time = (now1.tv_sec * 1000.0 + now1.tv_usec / 1000.0) 
					- (now.tv_sec * 1000.0 + now.tv_usec / 1000.0);
		printf("total time=%f ms\n", time);
	}

	// 关闭
	SpiClose();   
	return 0;
}
#endif


#if 0
//--------------------------------------------------------------------------------------------------
// 测试代码（测试spi网络层的代码）
//     1. 测试中断信号。
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
	int ret = 0;
	int cnts = 0;
	int value1;
	static char tx_buf[4*1024] = {0}; 
	struct timeval now;
	struct timeval now1;


	fpga_register_open();
	ret = spi_init();
	if (ret < 0)
	{
		dbg_error("spi_init() error \n");
		//return -1;
		goto exit1;
	}
	dbg_printf("spi_init() ok\n");
	sleep(1);
	
	for(int i=0; i<10; ++i)
	{
		sleep(1);
		++cnts;
		
		// 模拟发送中断,输出高脉冲
		dbg_printf("%d. GPIO2 output = 0 \n",  cnts);
		fpga_register_set(0x9c>>2, 0);
		usleep(100);
		value1= fpga_register_get(0x90>>2);
		dbg_printf("    GPIO1 input = %d \n",  value1);

		dbg_printf("    GPIO2 output = 1 \n");
		fpga_register_set(0x9c>>2, 1);
		usleep(1000);
		value1= fpga_register_get(0x90>>2);
		dbg_printf("    GPIO1 input = %d \n",  value1);
		fpga_register_set(0x9c>>2, 0);
	}

exit1:
	// 关闭
	spi_uninit();
	fpga_register_close();
	return 0;
}
#endif


#if 0
//--------------------------------------------------------------------------------------------------
// 测试代码（测试spi_uds接口协议）
//     1. 
//--------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
	int ret = 0;
	int cnts = 0;
	int value1;
	static char tx_buf[4*1024] = {0}; 
	input_signal_t   in = { 0 };
	output_signal_t  out = { 0 };

	fpga_register_open();
	ret = spi_init();   	///< 初始化
	if (ret < 0)
	{
		dbg_error("spi_init() error \n");
		//return -1;
		goto exit1;
	}
	dbg_printf("spi_init() ok\n");
	sleep(1);
	
	for(int i=0; i<10; ++i)
	{
		sleep(1);
		++cnts;
		
		ret =  spi_get_inputsignal(&in);   // 读取参数
		if (ret < 0)
		{
			dbg_error("spi_get_inputsignal() < 0\n");
		}

		out.alarminfo.fcw_level = 3;
		ret = spi_set_outputsignal(&out);
		if (ret < 0)
		{
			dbg_error("spi_set_outputsignal() < 0\n");
		}
	}

exit1:
	spi_uninit();      		///< 反初始化
	fpga_register_close();
	return 0;
}
#endif


#if 1
//--------------------------------------------------------------------------------------------------
// 测试代码（测试commucationIF协议）
//     1. 
//--------------------------------------------------------------------------------------------------
static udsrequest_t  uds_opt =
{
};

udsdtc_t dtcinfo ;
udsdid_t updatedid ;

int main(int argc, char *argv[])
{
	int ret = 0;
	int cnts = 0;
	int value1;
	static char tx_buf[4*1024] = {0}; 
	signal_t   in = { 0 };
	output_signal_t  out = { 0 };

	fpga_register_open();
	ret = spi_init( /*&uds_opt */);   	///< 初始化
	if (ret < 0)
	{
		dbg_error("CommucationInit() error \n");
		//return -1;
		goto exit1;
	}
	dbg_printf("CommucationInit() ok\n");
	sleep(1);
	
	while (1)
	{
		sleep(1);
		++cnts;
		
		spi_get_inputsignal(&in);   // 读取参数
		printf ("speed: %f Km/h \n", (double)in.speed/128.0);
		printf ("turnleft: %d   \n", in.left_light);
		printf ("turnright: %d  \n", in.right_light);
		printf ("brake: %d  \n", in.brake);
		printf ("reverse: %d  \n", in.reverse);
		printf ("ldw_on: %d  \n", in.ldw_on);
		printf ("fcw_on: %d  \n", in.fcw_on);
		printf ("pcw_on: %d  \n", in.pcw_on);
		printf ("hmw_on: %d  \n", in.hmw_on);
		printf ("steering_angle: %d  \n", (double)in.steering_angle/10.0);
		printf ("yaw_rate: %f  deg/s \n", (double)in.yaw_rate/100.0);


		// out.alarminfo.fcw_level = 2;
		// out.alarminfo.hmw_level = 3;
		// out.alarminfo.ldw = 1;
		// out.alarminfo.ttc = 1000;
		// out.alarminfo.ufcw = 1;
		// ret =  spi_set_outputsignal(&out.alarminfo, &out.objinfo);   // 发送参数
		// if (ret < 0)
		// {
		// 	dbg_error("spi_set_outputsignal() < 0\n");
		// }
	}

exit1:
	spi_uninit();      		///< 反初始化
	fpga_register_close();
	return 0;
}
#endif



